package com.emser.unc.client.presenter;

import com.emser.unc.client.CloudMobile;
import com.emser.unc.client.event.MenuEvent;
import com.emser.unc.client.helper.RPCCall;
import com.emser.unc.client.service.ProductServiceAsync;
import com.emser.unc.serializable.ProductDTO;
import com.emser.unc.serializable.UserAccountDTO;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;

public class ProductPopupPresenter implements Presenter {
	private final Display display;
	private ProductServiceAsync rpcProductService;
	private ProductDTO product;
	private SimpleEventBus eventBus;
	private UserAccountDTO userA;
	private boolean validFields;
	
	public interface Display {	
	    Widget asWidget();
	    HasText getCode();
	    HasValue<String> getPrice();
	    HasValue<String> getStock();	    
	    HasClickHandlers getSaveButton();
	    HasValue<String> getTitleProduct();
	    void setTextPopup(String text);
	    String getTextPopup();
	    void enableSave(boolean enabled);
	    void setVisibeWTitle(boolean visible);
	    void setVisibeWPrice(boolean visible);
	    void setVisibeWStock(boolean visible);
	    void hide();
		HasClickHandlers getCancelButton();
	  }
	
	public ProductPopupPresenter(SimpleEventBus eventBus,Display display,ProductServiceAsync rpcProductService){
		this.display = display;
		this.rpcProductService = rpcProductService;
		this.product = new ProductDTO();
		this.eventBus = eventBus;
		bind();
	}
	
	private void doEdit() {
		validateFields();
		if(!validFields){
			display.enableSave(true);
			return;
		}
		String price = display.getPrice().getValue();
		price = price.replace(",", ".");
		product.setStock(Long.parseLong(display.getStock().getValue()));
		product.setTitle(display.getTitleProduct().getValue());
		product.setUnitPrice(Double.parseDouble(price));
		new RPCCall<Boolean>(){
			@Override
			public void onFailure(Throwable caught) {
				display.hide();
				Window.alert(CloudMobile.constants.eEditProduct());
				display.enableSave(true);
			}
			@Override
			public void onSuccess(Boolean result) {
				display.hide();
				if(result.booleanValue())
					eventBus.fireEvent(new MenuEvent(CloudMobile.constants.menuProducts()));					
				else
					Window.alert(CloudMobile.constants.eServerEditProduct());
				display.enableSave(true);
			}
			@Override
			protected void callService(AsyncCallback<Boolean> cb) {
				rpcProductService.updateProduct(userA.getName(),product, cb);	
			}
		}.retry(2);
	}

	private void doAdd() {		
		disableWarningFields();
		validateFields();
		if(!validFields){
			display.enableSave(true);
			return;
		}
		String price = display.getPrice().getValue();
		price = price.replace(",", ".");
		product.setStock(Long.parseLong(display.getStock().getValue()));
		product.setUnitPrice(Double.parseDouble(price));
		product.setTitle(display.getTitleProduct().getValue());
		new RPCCall<Boolean>(){
			@Override
			public void onFailure(Throwable caught) {
				display.hide();
				Window.alert(CloudMobile.constants.eAddProduct());
				display.enableSave(true);
			}
			@Override
			public void onSuccess(Boolean result) {
				display.hide();
				if(result.booleanValue())
					eventBus.fireEvent(new MenuEvent(CloudMobile.constants.menuProducts()));					
				else
					Window.alert(CloudMobile.constants.eServerAddProduct());
				display.enableSave(true);
			}
			@Override
			protected void callService(AsyncCallback<Boolean> cb) {
				rpcProductService.addProduct(userA.getName(),product, cb);	
			}
		}.retry(2);
	}
	private void validateFields() {
		validFields = true;
		if (display.getTitleProduct().getValue().isEmpty()){
			display.setVisibeWTitle(true);
			validFields = false;
		}
		if (display.getPrice().getValue().isEmpty()||!(display.getPrice().getValue().matches( "([0-9]*)([,.]{0,1})(([0-9]*))" ))){
			display.setVisibeWPrice(true);
			validFields = false;
		}
		if (display.getStock().getValue().isEmpty()||!(display.getStock().getValue().matches( "([0-9]*)" ))){
			display.setVisibeWStock(true);
			validFields = false;
		}
	}

	private void disableWarningFields() {
		display.setVisibeWTitle(false);	
	}

	private void bind() {
		this.display.getSaveButton().addClickHandler(new ClickHandler() {   
		      public void onClick(ClickEvent event) {
		    	  display.enableSave(false);
		    	  if(display.getTextPopup().equals(CloudMobile.constants.titleEditProduct()))
		    		  doEdit();
		    	  else
		    		  doAdd();
		    	  
		      }
		});
		this.display.getCancelButton().addClickHandler(new ClickHandler() {   
		      public void onClick(ClickEvent event) {
		    	  doCancel();
		      }
		});
	}
	private void doCancel() {
		display.hide();
	}

	public void setUserA(UserAccountDTO userA) {
		this.userA = userA;
	}
	public void configPopup(UserAccountDTO userA,String title){
		this.userA = userA;
		display.setTextPopup(title);
	}
	public void configPopup(UserAccountDTO userA,String title,ProductDTO product){
		this.userA = userA;
		this.product = product;
		display.setTextPopup(title);
		setValuesDisplay(product);
	}
	
	public void setValuesDisplay(ProductDTO product){
		display.getCode().setText(product.getCode().toString());
		display.getPrice().setValue(product.getUnitPrice().toString());
		display.getTitleProduct().setValue(product.getTitle());
		display.getStock().setValue(product.getStock().toString());
	}

	@Override
	public void go(HasWidgets container) {}

}
